open Ast

let toPorte s = match (String.lowercase s) with
    "and" -> AND
  | "xor" -> XOR
  | "not" -> NOT
  | "or"  -> OR 
  | "reg" -> REG
  | "ram" -> RAM
  | "rom" -> ROM
  | _ -> failwith("pas un primitive");;

(*supprime de l'arbre les noeuds useless*)
let rec simplify = function
    Program(a,b) -> [Program(a,List.flatten (List.map simplify b))]
  | Bloc(a,b,c,d) -> [Bloc(a,b,c,List.flatten (List.map simplify d))]
  | Affectation(a,b) -> [Affectation(a,b)]
  | ListAffectation(a) -> a
  | _ -> failwith("erreur matching simplify")




(*les 2 fonctions qui suivent servent a l'affichage qui est assez clair pour l'instant*)
     
let afficheType = function
    IN -> print_string "I"
  | AND-> print_string "A"
  | OR-> print_string "O"
  | XOR-> print_string "X"
  | NOT-> print_string "N"
  | REGIN-> print_string "Q"
  | REGOUT -> print_string "R"
  | TRUE-> print_string "1"
  | FALSE-> print_string "0"
  | INIT-> print_string "init"
  | RAM -> print_string "M"
  | ROM -> print_string "P"
  | ROMOUT -> print_string "C"
  | RAMOUT -> print_string "B"
  | REG -> failwith("REG present dans afficheType");;
	     

let rmtoOut = function
  |RAM -> RAMOUT
  |ROM -> ROMOUT
  |_->failwith("erreur matching rmtoOut");;

let print b =
  print_int b.nbElem;print_newline();
  List.iter (fun x -> print_int x;print_newline()) b.sorties;print_newline();
  for i=0 to (b.nbElem-1) do
    print_int i;afficheType b.noeuds.(i);print_newline()
  done;
  for i=0 to (b.nbElem-1) do
    List.iter (function x -> print_int i;print_string " -> ";print_int x;print_newline()) b.ladj.(i)
  done;;

let printToken t = match t with
  |Grammar.EQUAL -> print_string "=";print_newline()
  |Grammar.LPAREN -> print_string "(";print_newline()
  |Grammar.RPAREN -> print_string ")";print_newline()
  |Grammar.NAME(id) -> print_string id;print_newline()
  |Grammar.RCURLY -> print_string "}";print_newline()
  |Grammar.LCURLY -> print_string "{";print_newline()
  |Grammar.COMMA -> print_string ",";print_newline()
  |Grammar.INCLUDE(n) -> print_string ("<- "^n);print_newline()
  |Grammar.FOR -> print_string "FOR";print_newline()
  |Grammar.ENTIER(n) -> print_int n;print_newline()
  |Grammar.BOOL(true) -> print_string "true";print_newline();
  |Grammar.BOOL(false) -> print_string "false";print_newline();
  |_ -> ();;

let rec printAst = function
    Program(a,b) -> print_string "Program\n";List.iter printAst b
  | Bloc(a,b,c,d) -> print_string ("Bloc "^a^"\n");List.iter printAst d
  | Affectation(a,b) -> List.iter (fun x->print_string (x^" <- \n")) a
  | _ -> failwith("erreur matching printAst")

(*permet au lexer de renvoyer des listes de tokens*)
let cache=ref [];;
let cacheHandler lexbuf =
  if !cache==[] then
    cache:=Tokens.token lexbuf;
  match !cache with
      x::t -> cache:=t;x
    | [] -> failwith("Tentative de lecture d'un buffer vide");;
